package strauss.flatland.things.geometry;

public abstract class VectorMath {
	public static GeometricVector delta(final GeometricVector a, final GeometricVector b) {
		return new GeometricVector(a.getXD()-b.getXD(), a.getYD()-b.getYD());
	}
	
	public static GeometricVector add(final GeometricVector a, final GeometricVector b) {
		return new GeometricVector(a.getXD()+b.getXD(), a.getYD()+b.getYD());
	}
	
	/** no silly!
	public static GeometricVector multiply(final GeometricVector a, final GeometricVector b) {
		return new GeometricVector(a.getXD()*b.getXD(),a.getYD()*b.getYD());
	}*/
	
	public static GeometricVector multiply(final GeometricVector a, final double scalar) {
		return new GeometricVector(a.getXD()*scalar,a.getYD()*scalar);
	}
	
	public static GeometricVector multiply(final GeometricVector a, final GeometricVector b) {
		return new GeometricVector(a.getXD()*b.getXD(),a.getYD()*b.getYD());
	}
	
	public static GeometricVector divide(final GeometricVector a, final double scalar) {
		return new GeometricVector(a.getXD()/scalar,a.getYD()/scalar);
	}
	
	public static GeometricVector crossProduct(final GeometricVector a, final GeometricVector b) {
		// cross product is not defined in 2-space
		return new GeometricVector(0, 0);
	}
	
	public static double dotProduct(final GeometricVector a, final GeometricVector b) {
		return a.getXD()*b.getXD() + a.getYD()*b.getYD();
	}
	
	// cos@ = u.v/||u||||v||
	// @ = cos-1(u.v/||u||||v||)
	public static double angleBetweenTwoVectors(final GeometricVector a, final GeometricVector b) {
		double dotProduct = VectorMath.dotProduct(a, b);
		double mA = VectorMath.getMagnitude(a);
		double mB = VectorMath.getMagnitude(b);
		double divisor=mA*mB;
		return divisor==0?0:Math.acos(dotProduct/divisor);
	}
	
	public static double getMagnitude(final GeometricVector a) {
		double tmp = a.getXD()*a.getXD() + a.getYD()*a.getYD();
		return tmp==0?0:Math.sqrt(tmp);
	}
		
	public static double angleOfVector(final GeometricVector a) {
		return angleBetweenTwoVectors(a, new GeometricVector(1,0));
	}
	
	/**
	 * make the magnitude of the vector 1
	 * @param a
	 * @return
	 */
	public static GeometricVector normalize(final GeometricVector a) {
		double m = getMagnitude(a);
		return m==0?new GeometricVector(0,0):new GeometricVector(a.getXD()/m, a.getYD()/m); 
	}
	
	public static boolean isZero(final GeometricVector a) {
		return a.getXD()==0&&a.getYD()==0;
	}	
}